package com.fordmotor.aspectj;


import com.alibaba.fastjson.JSON;
import com.fordmotor.util.IpUtil;
import junit.framework.TestCase;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.function.Function;

/**
 * @author THUNDEROBOT
 */
@Slf4j
public abstract class AbstractControllerHandler {

    private static Function<JoinPoint, AbstractControllerHandler> build;

    public static Function<JoinPoint, AbstractControllerHandler> getBuild() {
        return build;
    }

    public static void registerBuildFunction(Function<JoinPoint, AbstractControllerHandler> build) {
        TestCase.assertNotNull("build",build);
        AbstractControllerHandler.build = build;
    }

    protected JoinPoint joinPoint;
    protected HttpServletRequest httpServletRequest;
    protected String methodName;
    protected String uri;
    protected String requestBody;
    protected String ip;



    public AbstractControllerHandler(JoinPoint joinPoint) {
        TestCase.assertNotNull( "joinPoint",joinPoint);
        this.joinPoint = joinPoint;

        this.httpServletRequest = this.getHttpServletRequest(this.joinPoint.getArgs());
        this.uri = null == this.httpServletRequest ? null : this.httpServletRequest.getRequestURI();
        this.requestBody = this.formatParameters(this.joinPoint.getArgs());
        this.ip = null == this.httpServletRequest ? "" : IpUtil.getIpAddr(httpServletRequest);

    }
    protected abstract Object handle(JoinPoint joinPoint,Object rvt)throws Throwable;
    public abstract Object handle(String methodName,Object rvt) throws Throwable;



    protected HttpServletRequest getHttpServletRequest(Object[] parameters) {
        try {
            if (null != parameters) {
                for (Object parameter : parameters) {
                    if (parameter instanceof HttpServletRequest) {
                        return (HttpServletRequest) parameter;
                    }
                }
            }
            return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        } catch (Exception e) {
            log.error(e.getLocalizedMessage());
            return null;
        }
    }

    protected String formatParameters(Object[] parameters) {
        if (null == parameters) {
            return null;
        } else {
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < parameters.length; i++) {
                Object parameter = parameters[i];
                if (parameter instanceof HttpServletRequest || parameter instanceof HttpServletResponse) {
                    continue;
                }
                stringBuilder.append(String.format("[%s]: %s.", i, JSON.toJSONString(parameter)));
            }

            return stringBuilder.toString();
        }
    }
}
